package model.surface;

import model.utils.Speed;

/**
 * Class representing a simple point of the path on the screen. The point have
 * x, y coordinates and direction for the next point.
 * 
 * @author EvilTeam
 * 
 */
public class PathPoint extends ScreenPoint {

	private static final int RADIUS = 9;
	private static final int INVALID_DIRECTION = -1;
	private static final int MAX_NUM_FOR_DIRECTION = 3;
	private static final int MIN_NUM_FOR_DIRECTION = INVALID_DIRECTION;
	private int direction;

	public PathPoint(PathPointLoader scale) {
		super(scale.getxPoint(), scale.getyPoint());
		this.setDirection(scale.getDirection());
	}

	public PathPoint(float xPoint, float yPoint, boolean isTaken) {
		super(xPoint, yPoint, isTaken);
	}

	public int getDirection() {
		return direction;
	}

	public void setDirection(int direction) {
		if (direction >= MIN_NUM_FOR_DIRECTION
				&& direction <= MAX_NUM_FOR_DIRECTION)
			this.direction = direction;
	}

	/**
	 * Checks if a x, y coordinates of an object(enemy) on the map have
	 * collision with some of the path points.
	 * 
	 * @param pointX
	 *            - x point for the object
	 * @param pointY
	 *            - y point for the object
	 * @return Return's true if there is collision.
	 */
	public boolean isInThePathPoint(float pointX, float pointY) {
		if ((pointX > super.getxPoint() - RADIUS && pointX < super.getxPoint()
				+ RADIUS)
				&& ((pointY > super.getyPoint() - RADIUS && pointY < super
						.getyPoint() + RADIUS))) {
			return true;
		}
		return false;
	}

	/**
	 * Check if a x, y coordinates of an object(tower) are on some place on the
	 * path.
	 * 
	 * @param pointX
	 *            - x point for the object
	 * @param pointY
	 *            - y point for the object
	 * @param nextPoint
	 *            - next point of the path
	 * @return Return's true if the object is on the path.
	 */
	public boolean isOnThePath(float pointX, float pointY, PathPoint nextPoint) {
		switch (this.getDirection()) {
		case Speed.DIRECTION_RIGHT:
			for (float i = super.getxPoint(); i < nextPoint.getxPoint(); i++) {
				PathPoint newPoint = new PathPoint(i, super.getyPoint(), false);
				if (newPoint.checkForPathWidth(pointX, pointY)) {
					return true;
				}
			}
			break;
		case Speed.DIRECTION_DOWN:
			for (float i = super.getyPoint(); i < nextPoint.getyPoint(); i++) {
				PathPoint newPoint = new PathPoint(super.getxPoint(), i, false);
				if (newPoint.checkForPathWidth(pointX, pointY)) {
					return true;
				}
			}
			break;
		case Speed.DIRECTION_LEFT:
			for (float i = super.getxPoint(); i > nextPoint.getxPoint(); i--) {
				PathPoint newPoint = new PathPoint(i, super.getyPoint(), false);
				if (newPoint.checkForPathWidth(pointX, pointY)) {
					return true;
				}
			}
			break;
		case Speed.DIRECTION_UP:
			for (float i = super.getyPoint(); i > nextPoint.getyPoint(); i--) {
				PathPoint newPoint = new PathPoint(super.getxPoint(), i, false);
				if (newPoint.checkForPathWidth(pointX, pointY)) {
					return true;
				}
			}
			break;
		}
		return false;
	}

	/**
	 * Check if some object is in the path width.
	 * 
	 * @param pointX
	 *            - x point for the object
	 * @param pointY
	 *            - y point for the object
	 * @return Return's true if the object is in the path width.
	 */
	private boolean checkForPathWidth(float pointX, float pointY) {
		if ((pointX > super.getxPoint() - Map.getPathWidth() / 2 && pointX < super
				.getxPoint() + Map.getPathWidth() / 2)
				&& (pointY > super.getyPoint() - Map.getPathWidth() / 2 && pointY < super
						.getyPoint() + Map.getPathWidth() / 2))
			return true;
		return false;
	}

}
